#!/usr/bin/env python

import time, os
import wx 
import wx.gizmos as gizmos
from log_object import *

class DataFrame(wx.Frame):
	def __init__(self, parent, winsize, points):
		wx.Frame.__init__(self, parent, -1, "Log File Manager", points, size=(winsize[0],winsize[1]))
		self.selected_item = None 
		self.parent = parent

                self.treeListPanel = wx.Panel(self, -1, pos=(0,0), size=winsize, style=wx.NB_TOP)
                self.tree = gizmos.TreeListCtrl(self.treeListPanel, -1, size=winsize, style = wx.TR_DEFAULT_STYLE| wx.TR_FULL_ROW_HIGHLIGHT)
		#self.treeListPanel.SetBackgroundColour(wx.Colour(255, 255, 255)

		self.tree.AddColumn(" ")
		self.tree.SetColumnWidth(0, 150)
		self.tree.AddColumn("Date")
		self.tree.SetColumnWidth(1, 100)
		self.tree.AddColumn("Start ~")
		self.tree.SetColumnWidth(2, 100)
		self.tree.AddColumn("End")
		self.tree.SetColumnWidth(3, 100)
		self.tree.AddColumn("Duration")
		self.tree.SetColumnWidth(4, 80)
		self.tree.AddColumn("Particilants")
		self.tree.SetColumnWidth(5, 80)
		self.tree.AddColumn("Source")
		self.tree.SetColumnWidth(6, 250)
		self.tree.AddColumn("Tag")
		self.tree.SetColumnWidth(7, 100)
		self.tree.AddColumn("Active")
		self.tree.SetColumnWidth(8, 80)
		self.tree.AddColumn("Note")
		self.tree.SetColumnWidth(9, 80)
		self.tree.AddColumn("Video")
		self.tree.SetColumnWidth(10, 80)
		self.tree.AddColumn("Video Script")
		self.tree.SetColumnWidth(11, 100)

		self.tree.SetMainColumn(0)
		self.root = self.tree.AddRoot("User Study List")
		#self.tree.ExpandAll(self.root)
		self.tree.GetMainWindow().Bind(wx.EVT_RIGHT_DOWN, self.select_log)
		self.read_list()

	def read_list(self): 
		list = os.listdir(self.parent.db_dir)
		for dir in list :
			if dir[0] != '.' :
				db_case_item = self.parent.db_dir + dir + "/.db.list"
				if os.access(db_case_item, os.F_OK) == True :
					self.read_case_list(db_case_item)

	def read_case_list(self, info_file): 
		log_file_list = open(info_file, "r")
		line = log_file_list.readline()
		line = line.strip(' \t\n\r')
		report = self.tree.AppendItem(self.root, line)

		count =1
		while True :
			line = log_file_list.readline()
			if len(line) == 0 :
				break
			logdata = line.split()
			token_count = len(logdata) 
			if token_count > 0:
				log_item = self.tree.AppendItem(report, "study-" + str(count))

				# 4 1391742749.15 1391745852.8 dim_log_20140207-121229.log
				start_time = float(logdata[1])
				end_time = float(logdata[2])
				duration = int((end_time - start_time) / 60.0)

				# Thu Feb  6 21:12:29 2014 -> ['Thu', 'Feb', '6', '21:12:29', '2014'] 
				time_st = time.ctime(start_time)
				date_list = time_st.split()

				self.tree.SetItemText(log_item, date_list[4] + " " + date_list[1]+ " " + date_list[2], 1)
				self.tree.SetItemText(log_item, date_list[3], 2)
				time_st = time.ctime(end_time)
				date_list = time_st.split()
				self.tree.SetItemText(log_item, date_list[3], 3)
				self.tree.SetItemText(log_item, str(duration), 4)

				# participants
				self.tree.SetItemText(log_item, logdata[0], 5)
				# source
				self.tree.SetItemText(log_item, logdata[3], 6)
				count += 1;

				if token_count > 4 :
					self.tree.SetItemText(log_item, logdata[4], 7)

		log_file_list.close()

		self.tree.ExpandAll(self.root)

	def __load_data(self, filename, date, start, end, duration, participants, name):
		log_file = open(filename, "r")

		# to get starting time
		start =0
		while True :
			line = log_file.readline()
			if len(line) == 0 :
				break
			logdata = line.split()
			token_count = len(logdata) 
			if token_count > 0:
				if logdata[0] == "LOG":
					break;
		line = log_file.readline()
		if len(line) != 0 :
			logdata = line.split()
			token_count = len(logdata) 
			if token_count > 0:
				start = float(logdata[0])
		# display size
		line = log_file.readline()
		logdata = line.split()
		display = None
		if logdata[0] == "DISPLAY" : 
			display = (int(logdata[1]), int(logdata[2]))
		else : 
			display = (DISPLAY_WIDTH, DISPLAY_HEIGHT)

		log_obj = self.parent.createLog(start, duration, participants, name, date, display)

		while True :
			line = log_file.readline()
			if len(line) == 0 :
				break
			logdata = line.split()
			token_count = len(logdata) 
			if token_count > 3:
				if logdata[3] == "SECTION":
					if len(logdata[5]) == 20 : 
						log_obj.registerSection(logdata, start)
				elif logdata[3] == "POINTER":
					log_obj.registerPointer(logdata, start)
				elif logdata[3] == "WINDOW":
					log_obj.registerWindow(logdata, start)
		log_file.close()
		log_obj.sortingPointer()


	def select_log(self, event):
		self.selected_item = None 
		pos = event.GetPosition()
		idx, flags, col = self.tree.HitTest(pos)
		if col >= 0 :
			popupMenu = wx.Menu()
			self.selected_item = idx 
			log_filename = self.tree.GetItemText(self.selected_item, 6)
			if log_filename != "":
				popupMenu.Append(1, "&Load and Display")
				wx.EVT_MENU(popupMenu, 1, self.load)
				popupMenu.Append(2, "&Delete Log Item")
				wx.EVT_MENU(popupMenu, 2, self.delete_item)
			else:
				title = self.tree.GetItemText(self.selected_item, 0)
				if title == "User Study List" : 
					popupMenu.Append(1, "&Register Case")
					wx.EVT_MENU(popupMenu, 1, self.register_case)
				elif title != "" :
					popupMenu.Append(1, "&Import Log File ")
					wx.EVT_MENU(popupMenu, 1, self.add_item)
					popupMenu.Append(2, "&Remove Case")
					wx.EVT_MENU(popupMenu, 2, self.remove_case)
					popupMenu.Append(3, "&Load and Display")
					wx.EVT_MENU(popupMenu, 3, self.load)

			self.tree.PopupMenu(popupMenu, pos)
		return

	def test(self, first=True):
		# TODO: multiple selection or case selection
		self.parent.clearPanel()
		totalcount = self.tree.GetChildrenCount(self.root, False)
		print totalcount
		if totalcount > 0 :
			user = self.tree.GetFirstChild(self.root)
			user_item = user[0]
			datacount = self.tree.GetChildrenCount(user_item, False)
			if datacount > 0 :
				study = self.tree.GetFirstChild(user_item)
				case = self.tree.GetItemText(user_item, 0)
				print case
				child_item = study[0]
				print self.tree.GetItemText(child_item, 0)
				if first == False :
					child_item = self.tree.GetNextSibling(child_item)
				self.__log_item(child_item, case)
				tag = self.tree.GetItemText(child_item, 7)
				if len(tag) > 0 : 
					self.parent.registerPeriod(tag)

				for i in range(1, totalcount) :
					user_item = self.tree.GetNextSibling(user_item)
					case = self.tree.GetItemText(user_item, 0)
					print case

					study = self.tree.GetFirstChild(user_item)
					child_item = study[0]
					print self.tree.GetItemText(child_item, 0)
					if first == False :
						child_item = self.tree.GetNextSibling(child_item)
					self.__log_item(child_item, case)
					tag = self.tree.GetItemText(child_item, 7)
					if len(tag) > 0 : 
						self.parent.registerPeriod(tag)
		for log in self.parent.log_list : 	
			print log.start_time

		self.parent.showCanvas()


	def load(self, event):
		# TODO: multiple selection or case selection
		self.parent.clearPanel()
		log_filename = self.tree.GetItemText(self.selected_item, 6)
		if log_filename == "" :
			case = self.tree.GetItemText(self.selected_item, 0)
			if case != "User Study List" :
				totalcount = self.tree.GetChildrenCount(self.selected_item, False)
				if totalcount > 0 :
					child = self.tree.GetFirstChild(self.selected_item)
					child_item = child[0]
					self.__log_item(child_item, case)
					for i in range(1, totalcount) :
						child_item = self.tree.GetNextSibling(child_item)
						self.__log_item(child_item, case)
		else: 
			case_item = self.tree.GetItemParent(self.selected_item)
			case = self.tree.GetItemText(case_item, 0)
			self.__log_item(self.selected_item, case)

		self.parent.showCanvas()
		self.selected_item = None 


	def __log_item(self, item, case):
		log_filename = self.tree.GetItemText(item, 6)
		date = self.tree.GetItemText(item, 1)
		start = self.tree.GetItemText(item, 2)
		end = self.tree.GetItemText(item, 3)
		duration = int(self.tree.GetItemText(item, 4))
		participants = int(self.tree.GetItemText(item, 5))
		name = self.tree.GetItemText(item, 0)
		full_path = self.parent.db_dir + case + "/" + log_filename
		self.__load_data(full_path, date, start, end, duration, participants, name)
		
		tag = self.tree.GetItemText(item, 7)
		if len(tag) > 0 : 
			self.parent.registerTag(tag)


	def add_item(self, event):
                opendlg = wx.FileDialog(self, "Select a log file", ".", "", "*.log")
                ret = opendlg.ShowModal()
                path = opendlg.GetPath()
                source_path = path
                source_name = opendlg.GetFilename()
                # opendlg.GetDirectory()
                opendlg.Destroy()
                if ret == wx.ID_OK :
			# 1. check whether filename is duplicated or not
			duplicated = False
			total_count = self.tree.GetChildrenCount(self.selected_item, False)
			if total_count > 0 : 
				first_child = self.tree.GetFirstChild(self.selected_item)
				child_item = first_child[0]
				if self.tree.GetItemText(child_item, 6) == source_name : 
					duplicated = True 
					print "duplicated log"
				else :
					for i in range(1, total_count) :
						child_item = self.tree.GetNextSibling(child_item)
						if self.tree.GetItemText(child_item, 6) == source_name : 
							duplicated = True 
							print "duplicated log"
							braek
			# 2. if not, copy into the directory 
			if duplicated == False:
				item_title = self.tree.GetItemText(self.selected_item, 0)
				dir = self.parent.db_dir + item_title + "/"
				cmd = "cp -f \"" + source_path + "\" \"" + dir + "\""
				os.system(cmd)

				# 3. add info to .db.list :parsing is needed
				logdata = self.parse_and_write(dir, source_name)

				# 4. add it into the list
				# TODO: NEED TO SORT LATER
				log_item = self.tree.AppendItem(self.selected_item, "study-" + str(total_count+1))

				# 4 1391742749.15 1391745852.8 dim_log_20140207-121229.log
				start_time = float(logdata[1])
				end_time = float(logdata[2])
				duration = int((end_time - start_time) / 60.0)

				# Thu Feb  6 21:12:29 2014 -> ['Thu', 'Feb', '6', '21:12:29', '2014'] 
				time_st = time.ctime(start_time)
				date_list = time_st.split()

				self.tree.SetItemText(log_item, date_list[4] + " " + date_list[1]+ " " + date_list[2], 1)
				self.tree.SetItemText(log_item, date_list[3], 2)
				time_st = time.ctime(end_time)
				date_list = time_st.split()
				self.tree.SetItemText(log_item, date_list[3], 3)
				self.tree.SetItemText(log_item, str(duration), 4)

				# participants
				self.tree.SetItemText(log_item, str(logdata[0]), 5)
				# source
				self.tree.SetItemText(log_item, source_name, 6)

		self.selected_item = None 

	def delete_item(self, event):
		# 1. delete from .db.list
		case = self.tree.GetItemParent(self.selected_item)
		title = self.tree.GetItemText(case, 0)
		source = self.tree.GetItemText(self.selected_item, 6)
		dir = self.parent.db_dir + title + "/"
		in_file = open(dir + ".db.list", "r")
		line = in_file.readline()
		out_file = open(dir + "db.list", "w")
		out_file.write(line)
		logdata = []
		while True :
			line = in_file.readline()
			if len(line) == 0 :
				break
			logdata = line.split()
			token_count = len(logdata) 
			if token_count > 0:
				# 4 1391742749.15 1391745852.8 dim_log_20140207-121229.log
				token = logdata[3]
				if token != source:
					out_file.write(line)
		in_file.close()
		out_file.close()

		cmd = "mv \"" + dir + "db.list\" \"" + dir + ".db.list\""
		os.system(cmd)
		self.tree.Delete(self.selected_item)
		self.selected_item = None 

	def register_case(self, event):
		dlg = TextBoxDialog(self, "Add New User Study Case")
		dlg.Centre()
		ret = dlg.ShowModal()
		item_title = ""
		if ret == wx.ID_OK :
			item_title = dlg.txt.GetValue()
		dlg.Destroy()
		if item_title != "" :
			# 1. check whether title is duplicated or not
			duplicated = False
			total_count = self.tree.GetChildrenCount(self.root, False)
			if total_count > 0 : 
				first_child = self.tree.GetFirstChild(self.root)
				child_item = first_child[0]
				if self.tree.GetItemText(child_item, 0) == item_title : 
					duplicated = True 
					print "duplicated case"
				else :
					for i in range(1, total_count) :
						child_item = self.tree.GetNextSibling(child_item)
						if self.tree.GetItemText(child_item, 0) == item_title : 
							duplicated = True 
							print "duplicated case"
							braek
			# 2. if not, create directory in db 
			if duplicated == False:
				if os.access(self.parent.db_dir + item_title, os.F_OK) == False :
					os.mkdir(self.parent.db_dir + item_title)
				self.tree.AppendItem(self.root, item_title)

				# 3. create .db.list in the created directory
				out_file = open(self.parent.db_dir + item_title + "/.db.list", "w+")
				out_file.write(item_title +"\n")
				out_file.close()

		self.selected_item = None 

	def remove_case(self, event):
		# 1.  
		item_title = self.tree.GetItemText(self.selected_item, 0)
		if os.access(self.parent.db_dir + item_title + "/.db.list", os.F_OK) == True :
			os.rename(self.parent.db_dir + item_title + "/.db.list", self.parent.db_dir + item_title + "/inactive_db.list") 

		# 2. remove from the list
		self.tree.Delete(self.selected_item)

		self.selected_item = None 

	def parse_and_write(self, dir, source):
		# 1. find how many participants join to the User Study
		log_file = open(dir + source, "r")
		logdata = []
		start_time = "" 
		end_time = "" 
		user_list = []
		while True :
			line = log_file.readline()
			if len(line) == 0 :
				break
			logdata = line.split()
			token_count = len(logdata) 
			if token_count > 0:
				token = logdata[0]
				if token != '[' : 
					if token != 'LOG' and token != 'DISPLAY' and token[0] != '=' : 
						start_time = token 
				else :
					end_time =  logdata[1] 

					#['[', '1391742897.95', ']', 'POINTER', 'NEW', 'mouse', '192.168.0.31:Sanghwa']
					type = logdata[3] 
					if type == 'POINTER' : 
						sub_type = logdata[4] 
						if sub_type == 'NEW' :
							user_title = logdata[6]  
							# check whether user is new
							found = False
							user_count = len(user_list)	
							for i in range(user_count) : 
								user = user_list[i]
								if user_title == user :
									found = True 
									break;
							if found == False :
								user_list.append(user_title)
					del logdata[:]

		participants = len(user_list)
		del user_list[:]
		log_file.close()

		# 4 1391742749.15 1391745852.8 dim_log_20140207-121229.log
		out_file = open(dir + "/.db.list", "a+")
		out_file.write(str(participants) + " " + start_time + " " + end_time + " " + source +"\n")
		out_file.close()
		return (participants, start_time, end_time)


class TextBoxDialog(wx.Dialog):
	def __init__(self, parent, title):
		wx.Dialog.__init__(self, parent, -1, title, size=(300, 130), style= wx.STAY_ON_TOP)
		self.Center()
		vbox_top = wx.BoxSizer(wx.VERTICAL)
		self.txt = wx.TextCtrl(self, -1, "", size = (270, 25), style=wx.SUNKEN_BORDER )

		vbox_top.Add(self.txt, 0, wx.LEFT | wx.TOP | wx.BOTTOM, 15)
	
		grid = wx.GridSizer(1,2)
		okBtn = wx.Button(self, wx.ID_OK, "OK")
		grid.Add(okBtn)
		cancelBtn = wx.Button(self, wx.ID_CANCEL, "Cancel")
		grid.Add(cancelBtn, 0, wx.LEFT, 10)
		vbox_top.Add(grid, 0, wx.LEFT, 50)
		self.SetSizer(vbox_top)
		wx.EVT_KEY_UP(self, self.OnCharUp)

        def OnCharUp(self,event):
		keyid = event.GetKeyCode()
		if keyid == wx.WXK_RETURN :
			self.EndModal(wx.ID_OK)
		elif keyid == wx.WXK_ESCAPE :
			self.EndModal(wx.ID_CANCEL)
